package com.music.note_android.data.repository

import com.music.note_android.data.database.dao.FolderDao
import com.music.note_android.data.model.Folder
import com.music.note_android.data.model.SystemFolders
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.flow
import javax.inject.Inject
import javax.inject.Singleton

/**
 * 文件夹数据仓库实现类
 */
@Singleton
class FolderRepositoryImpl @Inject constructor(
    private val folderDao: FolderDao
) : FolderRepository {
    
    override suspend fun getAllFolders(): List<Folder> {
        val customFolders = folderDao.getAllFolders()
        return SystemFolders.getSystemFolders() + customFolders
    }
    
    override fun getAllFoldersFlow(): Flow<List<Folder>> {
        return folderDao.getAllFoldersFlow().combine(
            flow { emit(SystemFolders.getSystemFolders()) }
        ) { customFolders, systemFolders ->
            systemFolders + customFolders
        }
    }
    
    override suspend fun getFoldersWithNoteCount(): List<Folder> {
        val customFolders = folderDao.getFoldersWithNoteCount().map { it.toFolder() }
        
        // 获取系统文件夹的笔记数量
        val allNotesCount = folderDao.getAllNoteCount()
        val uncategorizedCount = folderDao.getUncategorizedNoteCount()
        
        val systemFolders = listOf(
            SystemFolders.ALL_NOTES_FOLDER.copy(noteCount = allNotesCount),
            SystemFolders.UNCATEGORIZED_FOLDER.copy(noteCount = uncategorizedCount)
        )
        
        return systemFolders + customFolders
    }
    
    override fun getFoldersWithNoteCountFlow(): Flow<List<Folder>> {
        return folderDao.getFoldersWithNoteCountFlow().combine(
            flow {
                val allNotesCount = folderDao.getAllNoteCount()
                val uncategorizedCount = folderDao.getUncategorizedNoteCount()
                emit(
                    listOf(
                        SystemFolders.ALL_NOTES_FOLDER.copy(noteCount = allNotesCount),
                        SystemFolders.UNCATEGORIZED_FOLDER.copy(noteCount = uncategorizedCount)
                    )
                )
            }
        ) { customFoldersWithCount, systemFolders ->
            val customFolders = customFoldersWithCount.map { it.toFolder() }
            systemFolders + customFolders
        }
    }
    
    override suspend fun getFolderById(folderId: String): Folder? {
        return when {
            SystemFolders.isSystemFolder(folderId) -> {
                when (folderId) {
                    SystemFolders.ALL_NOTES -> {
                        val count = folderDao.getAllNoteCount()
                        SystemFolders.ALL_NOTES_FOLDER.copy(noteCount = count)
                    }
                    SystemFolders.UNCATEGORIZED -> {
                        val count = folderDao.getUncategorizedNoteCount()
                        SystemFolders.UNCATEGORIZED_FOLDER.copy(noteCount = count)
                    }
                    else -> null
                }
            }
            else -> folderDao.getFolderById(folderId)
        }
    }
    
    override suspend fun createFolder(name: String): Result<Folder> {
        return try {
            // 验证文件夹名称
            val validation = validateFolderName(name)
            if (validation is ValidationResult.Invalid) {
                return Result.failure(IllegalArgumentException(validation.message))
            }
            
            val folder = Folder(
                name = name.trim(),
                createdTime = System.currentTimeMillis()
            )
            
            folderDao.insertFolder(folder)
            Result.success(folder)
        } catch (e: Exception) {
            Result.failure(e)
        }
    }
    
    override suspend fun updateFolder(folder: Folder): Result<Unit> {
        return try {
            // 系统文件夹不能更新
            if (folder.isSystem) {
                return Result.failure(IllegalArgumentException("系统文件夹不能修改"))
            }
            
            folderDao.updateFolder(folder)
            Result.success(Unit)
        } catch (e: Exception) {
            Result.failure(e)
        }
    }
    
    override suspend fun renameFolder(folderId: String, newName: String): Result<Unit> {
        return try {
            // 系统文件夹不能重命名
            if (SystemFolders.isSystemFolder(folderId)) {
                return Result.failure(IllegalArgumentException("系统文件夹不能重命名"))
            }
            
            // 验证新名称
            val validation = validateFolderName(newName, folderId)
            if (validation is ValidationResult.Invalid) {
                return Result.failure(IllegalArgumentException(validation.message))
            }
            
            val folder = folderDao.getFolderById(folderId)
                ?: return Result.failure(IllegalArgumentException("文件夹不存在"))
            
            val updatedFolder = folder.copy(name = newName.trim())
            folderDao.updateFolder(updatedFolder)
            Result.success(Unit)
        } catch (e: Exception) {
            Result.failure(e)
        }
    }
    
    override suspend fun deleteFolder(folderId: String): Result<Unit> {
        return try {
            // 系统文件夹不能删除
            if (SystemFolders.isSystemFolder(folderId)) {
                return Result.failure(IllegalArgumentException("系统文件夹不能删除"))
            }
            
            // 检查文件夹是否为空
            val noteCount = folderDao.getNoteCountInFolder(folderId)
            if (noteCount > 0) {
                return Result.failure(IllegalArgumentException("请先移出文件夹中的笔记"))
            }
            
            folderDao.deleteFolderById(folderId)
            Result.success(Unit)
        } catch (e: Exception) {
            Result.failure(e)
        }
    }
    
    override suspend fun moveNoteToFolder(noteId: String, folderId: String?): Result<Unit> {
        return try {
            // 如果是系统文件夹，转换为实际的数据库值
            val actualFolderId = when (folderId) {
                SystemFolders.ALL_NOTES -> null // 所有笔记实际上是显示所有，不改变folder_id
                SystemFolders.UNCATEGORIZED -> null
                else -> folderId
            }
            
            folderDao.moveNoteToFolder(noteId, actualFolderId)
            Result.success(Unit)
        } catch (e: Exception) {
            Result.failure(e)
        }
    }
    
    override suspend fun moveNotesToFolder(noteIds: List<String>, folderId: String?): Result<Unit> {
        return try {
            // 如果是系统文件夹，转换为实际的数据库值
            val actualFolderId = when (folderId) {
                SystemFolders.ALL_NOTES -> null
                SystemFolders.UNCATEGORIZED -> null
                else -> folderId
            }
            
            folderDao.moveNotesToFolder(noteIds, actualFolderId)
            Result.success(Unit)
        } catch (e: Exception) {
            Result.failure(e)
        }
    }
    
    override suspend fun validateFolderName(name: String, excludeId: String?): ValidationResult {
        val trimmedName = name.trim()
        
        // 检查名称是否为空
        if (trimmedName.isEmpty()) {
            return ValidationResult.Invalid("请输入文件夹名称")
        }
        
        // 检查长度限制
        if (trimmedName.length > 50) {
            return ValidationResult.Invalid("文件夹名称不能超过50个字符")
        }
        
        // 检查非法字符
        val illegalChars = listOf('/', '\\', ':', '*', '?', '"', '<', '>', '|')
        if (trimmedName.any { it in illegalChars }) {
            return ValidationResult.Invalid("文件夹名称包含非法字符")
        }
        
        // 检查系统保留名称
        if (trimmedName == "所有笔记" || trimmedName == "未分类") {
            return ValidationResult.Invalid("不能使用系统保留名称")
        }
        
        // 检查重名
        val count = if (excludeId != null) {
            folderDao.countFoldersByNameExcluding(trimmedName, excludeId)
        } else {
            folderDao.countFoldersByName(trimmedName)
        }
        
        if (count > 0) {
            return ValidationResult.Invalid("文件夹名称已存在")
        }
        
        return ValidationResult.Valid
    }
    
    override suspend fun canDeleteFolder(folderId: String): Boolean {
        // 系统文件夹不能删除
        if (SystemFolders.isSystemFolder(folderId)) {
            return false
        }
        
        // 只有空文件夹才能删除
        val noteCount = folderDao.getNoteCountInFolder(folderId)
        return noteCount == 0
    }
}